﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

using GpsTagger.Logic;
using GpsTagger.Interface;

namespace GpsTagger
{
    public partial class mainFrm : Form
    {
        private string copyrightField;

        public string CopyrightField
        {
            get { return copyrightField; }
            set { copyrightField = value; }
        }

        public mainFrm()
        {
            InitializeComponent();

            copyrightField = "";
        }

        private void LoadFiles_Click(object sender, EventArgs e)
        {
            DialogResult dr = loadFilesDialog.ShowDialog();
            if (dr == DialogResult.OK)
            {
                string[] filenames = loadFilesDialog.FileNames;
                for (int i = 0; i < filenames.Length; i++)
                {
                    ImageInfo info = new ImageInfo(filenames[i], "[NOT TAGGED]");
                    fileList.Items.Add(info);
                }
            }
        }

        private void ClearFiles_Click(object sender, EventArgs e)
        {
            fileList.Items.Clear();
        }

        private void LoadMapPoints_Click(object sender, EventArgs e)
        {
            DialogResult dr = openKMLFile.ShowDialog();
            if (dr == DialogResult.OK)
            {
                string usedFileName = openKMLFile.FileName;
                gpsLocation.Items.Clear();                
                Queue<MapPoint> tmpQueue = new Queue<MapPoint>();
                KMLParser kp = new KMLParser(usedFileName);
                kp.ParseFile();
                kp.GetPoints(tmpQueue);
                for (int i = 0; i < tmpQueue.Count; i++)
                {
                    gpsLocation.Items.Add(tmpQueue.ElementAt(i));
                }
            }
        }

        private void TagPictures()
        {
            MapPoint mp = (MapPoint)gpsLocation.SelectedItem;
            if (mp == null)
            {
                return;
            }

            ListBox.SelectedObjectCollection selectedImages = fileList.SelectedItems;

            Queue<Object> modifiedImages = new Queue<object>();
            foreach (object obj in selectedImages)
            {
                ImageInfo img = (ImageInfo)obj;
                img.Tag(mp);

                modifiedImages.Enqueue(obj);
            }

            int imageCount = modifiedImages.Count;
            for (int i = 0; i < imageCount; i++)
            {
                object reinsertedImage = modifiedImages.Dequeue();
                fileList.Items.Remove(reinsertedImage);
                fileList.Items.Add(reinsertedImage);
                int indexToSelect = fileList.Items.IndexOf(reinsertedImage);
                fileList.SetSelected(indexToSelect, true);
            }

            fileList.Invalidate(true);
        }

        private void tagSingle_Click(object sender, EventArgs e)
        {
            TagPictures();
        }

        private void gpsLocation_DoubleClick(object sender, EventArgs e)
        {
            TagPictures();
        }

        private void fileList_SelectedIndexChanged(object sender, EventArgs e)
        {
            ListBox.SelectedObjectCollection selectedImages = fileList.SelectedItems;
            if (selectedImages.Count == 1)
            {
                ImageInfo imageToDisplay = (ImageInfo)fileList.SelectedItem;
                if (imageToDisplay != null)
                {
                    try
                    {
                        Bitmap imageToLoad = new Bitmap(imageToDisplay.FileName);

                        float widthRatio = ((float)imageToLoad.Width) / diplayPicture.Width;
                        float heightRatio = ((float)imageToLoad.Height) / diplayPicture.Height;
                        float usedRatio = widthRatio > heightRatio ? widthRatio : heightRatio;

                        int usedWidth = (int)(imageToLoad.Width / usedRatio);
                        int usedHeight = (int)(imageToLoad.Height / usedRatio);

                        int baseHorizontal = (int)(((float)(diplayPicture.Width - usedWidth)) / 2);
                        int baseVertical = (int)(((float)(diplayPicture.Height - usedHeight)) / 2);

                        diplayPicture.Image = new Bitmap(diplayPicture.Width, diplayPicture.Height);

                        Graphics grph = Graphics.FromImage(diplayPicture.Image);
                        Rectangle sourceRectangle = new Rectangle(new Point(0, 0), new Size(imageToLoad.Width, imageToLoad.Height));
                        Rectangle destinationRectange = new Rectangle(new Point(0, 0), new Size(usedWidth, usedHeight));
                        destinationRectange.Offset(baseHorizontal, baseVertical);
                        grph.DrawImage(imageToLoad, destinationRectange, sourceRectangle, GraphicsUnit.Pixel);
                        imageToLoad.Dispose();
                        imageToLoad = null;
                        return;
                    }
                    catch(Exception ex)
                    {}
                }
            }
            diplayPicture.Image = null;
        }

        private void ClearMapPoints_Click(object sender, EventArgs e)
        {
            gpsLocation.Items.Clear();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            diplayPicture.Image = null;
            (new taggerFrm(fileList.Items,CopyrightField)).ShowDialog();            
        }

        private void mainFrm_Resize(object sender, EventArgs e)
        {
            fileList_SelectedIndexChanged(this, new EventArgs());
        }

        private void helpToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Hoover your mouse over different buttons" + Environment.NewLine + "to see a brief description of their function", "Help", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {            
            (new aboutBoxFrm()).ShowDialog();
        }

        private void configureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new settingsFrm(this)).ShowDialog();
        }

        private void mainFrm_Load(object sender, EventArgs e)
        {
            try
            {
                StreamReader settings = new StreamReader("settings.txt");
                this.CopyrightField = settings.ReadToEnd();
                if (this.copyrightField.Length > 20)
                    this.copyrightField = "";
                settings.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to load copyright string." +Environment.NewLine+"This is normal if it is the first application run", "Copyright string NOT loaded", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            /* check to see if exiftool is there */
            string exiftoolPath = Application.StartupPath + "\\exiftool.exe";
            PictureTagger pt = new PictureTagger(exiftoolPath);
            if (!pt.ValidTagger())
            {
                MessageBox.Show("Failed to locate exiftool. " + Environment.NewLine + "Tool expected to be in: " + exiftoolPath, "exiftool NOT found", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }
        }

        private void mainFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                StreamWriter settings = new StreamWriter("settings.txt",false);
                settings.Write(this.copyrightField);
                settings.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to save copyright string!");
            }
        }

        private void ImageList_Enter(object sender, EventArgs e)
        {

        }
    }
}
